//
//  ExtractAstNode.m
//  WebClipper
//
//  Created by Daniel Braun on 10/06/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "ExtractAstNode.h"
#import "DBLexer.h"
#import "StringExtension.h"

@implementation ExtractAstNode

- (id) evaluateWithDictionary:(NSDictionary *) d
{
	return [(ExtractAstNode *)right evaluateWithDictionary:d];
}

+ (id) astNodeWithToken:(DBLexerTokenMatch *) t
{
	int tv=[t tokval];
	switch (tv) {
		case TOK_ID:
			return [[[IdExtractAstNode alloc]initWithToken:t]autorelease];
			break;
		case TOK_NUM:
			return [[[NumExtractAstNode alloc]initWithToken:t]autorelease];
			break;
		case TOK_ADDOP:
			return [[[OpExtractAstNode alloc]initWithToken:t]autorelease];
			break;
		case TOK_MULTOP:
			return [[[OpExtractAstNode alloc]initWithToken:t]autorelease];
			break;
		default:
			return [[[[self class]alloc]initWithToken:t]autorelease];
			break;
	}
	return nil;
}

@end

@implementation NumExtractAstNode
- (id) evaluateWithDictionary:(NSDictionary *) d
{
	NSString *s=[tok matchString];
	NSNumber *n=[s numberSmartValue];
	return n;
}
@end
@implementation IdExtractAstNode
- (id) evaluateWithDictionary:(NSDictionary *) d
{
	NSString *s=[tok matchString];
	id v=[d objectForKey:s];
	return v ? v : s;
}
@end

@implementation OpExtractAstNode
- (id) evaluateWithDictionary:(NSDictionary *) d
{
	id l,r;
	l=[(ExtractAstNode *)left evaluateWithDictionary:d];
	r=[(ExtractAstNode *)right evaluateWithDictionary:d];
	if (([l isKindOfClass:[NSString class]]) || ([r isKindOfClass:[NSString class]])) {
		return [NSString stringWithFormat:@" %@ %@ %@ ",
			l,[tok matchString],r];
	}
	if (![l isKindOfClass:[NSNumber class]]) return nil;
	if (![r isKindOfClass:[NSNumber class]]) return nil;
	double dl,dr;
	dl=[l doubleValue];
	dr=[r doubleValue];
	double res;
	NSString *s=[tok matchString];
	if ([s isEqualToString:@"+"]) {
		res=dl+dr;
	} else if ([s isEqualToString:@"-"]) {
		res=dl-dr;
	} else if ([s isEqualToString:@"*"]) {
		res=dl+dr;
	} else if ([s isEqualToString:@"/"]) {
		res=dl/dr;
	} else {
		return nil;
	}
	return [NSNumber numberWithDouble:res];

}
@end

